package com.atguigu.study.locks;

import org.openjdk.jol.info.ClassLayout;

import java.util.concurrent.TimeUnit;

/**
 * @auther zzyybs@126.com
 * @Date 2025-04-27 16:44
 * @Description: TODO
 *
 *  *
 *  * 先配置JVM参数：
 *  *
 *  * #开启偏向锁
 *  * -XX:+UseBiasedLocking
 *  *
 *  * #关闭偏向锁有延时
 *  * -XX:BiasedLockingStartupDelay=0
 */

public class LockUpDemo
{

    /**
     * 代码演示锁膨胀过程
     * @param args
     */
    public static void main(String[] args)
    {
        //biasable(); //测试01,可偏向，意思是当前 JVM 开启了偏向锁功能（此时锁的状态是无锁状态）

        //biased();   //测试02,偏向锁
        //thin();     //测试03,轻量级锁
        fat();      //测试04,重量级锁
    }


    /** JOL = java Object Layout
     * 测试01
     * 可偏向，意思是当前 JVM 开启了偏向锁功能（此时锁的状态是无锁状态）
     */
    private static void biasable()
    {
        // 1、创建一个对象作为锁对象
        Object lock = new Object();
        // 2、没有线程申请锁
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    }

    /**
     * 测试02
     * 从可偏向，意思是当前 JVM 开启了偏向锁功能（此时锁的状态是无锁状态)  到 偏向锁
     * 无锁状态 → 偏向锁
     */
    private static void biased()
    {
        // 1、创建一个对象作为锁对象
        Object lock = new Object();
        // 2、没有线程申请锁
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        // 3、main 线程申请锁
        synchronized (lock)
        {
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
    }


    /**
     * 测试03
     * 偏向锁 → 轻量级锁
     */
    private static void thin()
    {
        // 1、创建一个对象作为锁对象
        Object lock = new Object();
        // 2、没有线程申请锁
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        // 3、同一个Main线程多次申请锁
        synchronized (lock)
        {
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
        synchronized (lock)
        {
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
        synchronized (lock)
        {
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
        // 4、创建子线程A申请锁
        new Thread(() -> {
            synchronized (lock) {
                System.out.println(ClassLayout.parseInstance(lock).toPrintable());
            }
        }, "thread-a").start();
    }


    /**
     *测试04
     * 升级至重量级锁的代码
     */
    private static void fat()
    {
        // 1、创建一个对象作为锁对象
        Object lock = new Object();
        // 2、没有线程申请锁
        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        // 3、同一个Main线程多次申请锁
        synchronized (lock)
        {
            System.out.println(ClassLayout.parseInstance(lock).toPrintable());
        }
        // 4、创建两个线程申请锁
        new Thread(() -> {
            synchronized (lock) {
                while (true) {
                }
            }
        }, "thread-a").start();

        new Thread(() -> {
            synchronized (lock) {
                while (true) {
                }
            }
        }, "thread-b").start();

        //暂停几秒钟线程
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(ClassLayout.parseInstance(lock).toPrintable());
    }
}

